package com.github.glomadrian.roadrunner;

import com.github.glomadrian.roadrunner.painter.configuration.PathPainterConfiguration;
import com.github.glomadrian.roadrunner.painter.configuration.factory.PathPainterConfigurationFactory;
import com.github.glomadrian.roadrunner.painter.determinate.DeterminatePainter;
import com.github.glomadrian.roadrunner.painter.determinate.ProgressDeterminatePainter;
import com.github.glomadrian.roadrunner.painter.determinate.factory.DeterminatePainterFactory;
import com.github.glomadrian.roadrunner.path.PathContainer;
import com.github.glomadrian.roadrunner.utils.AssertUtils;
import com.github.glomadrian.roadrunner.utils.RangeUtils;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.app.Context;

import java.text.ParseException;

/**
 * Created by Yahya Bayramoglu on 08/04/16.
 */
public class ProgressRoadRunner extends RoadRunner implements Component.DrawTask {

    private static final String TAG = "ProgressRoadRunner";
    public static final String PROGRESS = "progress";
    private int originalWidth;
    private int originalHeight;
    private String pathData;
    private PathContainer pathContainer;
    private ProgressDeterminatePainter progressDeterminatePainter;

    private int min = 0;
    private int max = 100;
    private int progress = 0;

    private PathPainterConfiguration pathPainterConfiguration;
    private boolean firstDraw = true;
    private int tag;

    /**
     * ProgressRoadRunner
     *
     * @param context
     * @param attrs
     */
    public ProgressRoadRunner(Context context, AttrSet attrs) {
        super(context, attrs);
        initPath(attrs);
        initConfiguration(attrs);
        invalidate();
    }

    /**
     * ProgressRoadRunner
     *
     * @param context
     * @param attrs
     * @param defStyleAttr
     */
    public ProgressRoadRunner(Context context, AttrSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initPath(attrs);
        initConfiguration(attrs);
    }

    /**
     * getPaint
     *
     * @return progressDeterminatePainter.getPaint()
     */
    public Paint getPaint() {
        return progressDeterminatePainter.getPaint();
    }

    /**
     * setProgress
     *
     * @param value
     */
    public void setProgress(int value) {
        if (value <= max || value >= min) {
            this.progress = value;
            float progress = RangeUtils.getFloatValueInRange(min, max, 0f, 1f, value);
            if (progressDeterminatePainter != null) {
                progressDeterminatePainter.setProgress(progress);
            }
        }
    }

    /**
     * getProgress
     *
     * @return progress
     */
    public int getProgress() {
        return progress;
    }

    /**
     * getMin
     *
     * @return min
     */
    public int getMin() {
        return min;
    }

    /**
     * setMin
     *
     * @param min
     */
    public void setMin(int min) {
        this.min = min;
    }

    /**
     * getMax
     *
     * @return max
     */
    public int getMax() {
        return max;
    }

    /**
     * setMax
     *
     * @param max
     */
    public void setMax(int max) {
        this.max = max;
    }

    @Override
    public void setColor(int color) {
        progressDeterminatePainter.setColor(color);
    }

    /**
     * onSizeChanged
     *
     * @param w
     * @param h
     */
    protected void onSizeChanged(int w, int h) {
        try {
            pathContainer = buildPathData(w, h, pathData, originalWidth, originalHeight);
            initPathPainter();
        } catch (ParseException e) {
           // System.out.println(TAG + "Path parse exception:" + e.getMessage());
        }
    }

    @Override
    public void invalidate() {
        super.invalidate();
        this.addDrawTask(this::onDraw);
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        tag ++;
        if (tag == 1) {
            onSizeChanged(this.getWidth(), this.getHeight());
        }
        if (progressDeterminatePainter == null)
            return;
        if (!firstDraw) {
            progressDeterminatePainter.paintPath(canvas);
        } else {
            firstDraw = false;
        }
    }
    private void initPath(AttrSet attrs) {
        pathData = attrs.getAttr("path_data").get().getStringValue();
        originalWidth = attrs.getAttr("path_original_width").get().getIntegerValue();
        originalHeight = attrs.getAttr("path_original_height").get().getIntegerValue();
        AssertUtils.assertThis(pathData != null, "Path data must be defined", this.getClass());
        AssertUtils.assertThis(!pathData.isEmpty(), "Path data must be defined", this.getClass());
        AssertUtils.assertThis(!pathData.equals(""), "Path data must be defined", this.getClass());
        AssertUtils.assertThis(originalWidth > 0, "Original with of the path must be defined",
                this.getClass());
        AssertUtils.assertThis(originalHeight > 0, "Original height of the path must be defined",
                this.getClass());
    }

    private void initConfiguration(AttrSet attrs) {
        min = attrs.getAttr("min").get().getIntegerValue();
        max = attrs.getAttr("max").get().getIntegerValue();
        pathPainterConfiguration =
                PathPainterConfigurationFactory.makeConfiguration(attrs, DeterminatePainter.PROGRESS);
    }

    private void initPathPainter() {
        progressDeterminatePainter = (ProgressDeterminatePainter) DeterminatePainterFactory.makeIndeterminatePathPainter(
                DeterminatePainter.PROGRESS, pathContainer, this, pathPainterConfiguration);
    }

}